<template>
	<view class="bg-white" style="width:100%;" v-if="allField.length > 0">
		<!-- <scroll-view scroll-x="false" scroll-y="true"> -->
		<view v-for="(item, index) in allField" :key="index">
			<formItem
				:field="item"
				:pageFormType="BxformType"
				:showTextarea="showTextarea"
				:fieldsModel="fieldModel"
				ref="fitem"
				@on-form-item="onItemButtons($event)"
				@on-value-change="onValChange($event)"
				@on-value-blur="onValBlur($event)"
				@get-cascader-val="getCascaderVal"
			></formItem>
		</view>
		<!-- </scroll-view> -->
	</view>
</template>

<script>
import formItem from '@/components/bx-form/bx-form-item.vue';
export default {
	name: 'bx-form',
	components: { formItem },
	props: {
		fields: {
			type: Array,
			default() {
				return [];
			}
		},
		pageType: {
			type: String,
			default() {
				return '';
			}
		},
		BxformType: {
			type: String,
			default() {
				return 'form';
			}
		},
		showTextarea: {
			type: Boolean,
			default: true
		},
		moreConfig: {
			type: Object,
			default() {
				return {};
			}
		}
	},
	computed: {
		fieldsData: function() {
			return this.fields;
		}
	},
	data() {
		return {
			allField: this.fields,
			fieldModel: {},
			fieldData: {},
			oldFieldModel: {},
			specialCol: [],
			more_config: {
				col_relation: [
					{
						watch_col: ['page_end', 'page_start'], //相关字段
						dest_col: 'page', //页数
						value: {
							type: 'calc', //col  || calc 计算或者某字段对应值
							value: {
								type: 'sub', //减
								value: [
									{
										type: 'col',
										val: 'page_end'
									},
									{
										type: 'col',
										val: 'page_start'
									},
									{
										type: 'value',
										val: '-1'
									}
								]
							}
						}
					}
				],
				service_call_cfg: [
					{
						app: 'salesroom',
						service: 'srvsalesroom_print_price_calc_select',
						watch_col: ['page', 'paper_type', 'duplex_print', 'color'],
						req: {
							condition: [
								{
									colName: 'page_num',
									ruleType: 'eq',
									value: {
										valueType: 'rowData',
										valueKey: 'page'
									}
								},
								{
									colName: 'paper_type',
									ruleType: 'eq',
									value: {
										valueType: 'rowData',
										valueKey: 'paper_type'
									}
								},
								{
									colName: 'duplex_print',
									ruleType: 'eq',
									value: {
										valueType: 'rowData',
										valueKey: 'duplex_print'
									}
								},
								{
									colName: 'color',
									ruleType: 'eq',
									value: {
										valueType: 'rowData',
										valueKey: 'color'
									}
								}
							]
						}
					}
				]
			}
		};
	},
	created() {
		this.oldField = this.deepClone(this.fields);
		this.oldField.forEach((item, index) => {
			this.oldFieldModel[item.column] = item.value;
		});
		console.log(this.oldField, this.oldFieldModel);
		this.getAllField();
	},
	mounted() {
		const specialCol = this.$route.query.specialCol;
		if (specialCol) {
			try {
				debugger;
				this.specialCol = JSON.parse(decodeURIComponent(specialCol));
			} catch (e) {
				//TODO handle the exception
			}
		}
	},
	methods: {
		formulaEvaluator() {
			let formula = {
				if: {
					and: {
						eq: {
							// var:'', //var-变量
							col: 'is_huzhu', //col-字段名
							val: '是' // val-要比较的值
						},
						eq: {
							// var:'', //var-变量
							col: 'fwyt', //col-字段名
							val: '自住' // val-要比较的值
						}
					},
					t: true, //true-value 比较结果为true时返回的值
					f: false // false-value 比较结果为false时返回的值
				}
			};
			let rowData = {
				is_huzhu:"是",
				fwut:"自住"
			}
			let evaluator = function(formula,result) {
				Object.keys(formula).forEach(operator => {
					switch (operator) {
						case 'if': //if(xx){}else{}
							result = evaluator(operator[Object.keys(operator)[0]],result)?operator.t:operator.f
							return result
							break;
						case 'and': // &&
							result = evaluator(operator[Object.keys(operator)[0]],result)?true:false
							return result
							break;
						case 'eq': //等于 === equal
						  result = rowData[operator.col]===operator.val
							return result
							break;
					}
				});
				return result
			};
		},
		setRelationColumnValue(allField, colArr, col_relation) {
			const self = this;
			let more_config = self.more_config;
			let returnValue = null;
			switch (col_relation.value.type) {
				case 'calc': //计算
					(() => {
						let valueArr = col_relation.value.value.value.map(relationitem => {
							if (relationitem.type === 'col') {
								const finalArr = colArr.filter(col => col.column === relationitem.val);
								if (finalArr.length > 0) {
									return finalArr[0].value;
								}
							} else if (relationitem.type === 'value') {
								return Number(relationitem.val);
							}
						});
						switch (col_relation.value.value.type) {
							case 'add': //加
								valueArr.forEach(item => {
									returnValue += Number(item);
								});
								break;
							case 'sub': //减
								(() => {
									let result = 0;
									if (Array.isArray(valueArr) && valueArr.length > 0) {
										valueArr.forEach((item, index) => {
											if (index !== 0) {
												result += item;
											}
										});
										returnValue = valueArr[0] - result;
									}
								})();
								// returnValue = valueArr[0] - valueArr[1];
								break;
							case 'multi': //乘
								returnValue = 1;
								valueArr.forEach(item => {
									returnValue *= Number(item);
								});
								break;
							case 'divide': //除
								returnValue = valueArr[0] / valueArr[1];
								break;
						}
					})();
					break;
				case 'col': //字段对应值
					(() => {
						this.allField.forEach(col => {
							if (col.column === col_relation.value.value) {
								returnValue = col.value;
							}
						});
					})();
					break;
			}
			this.allField.forEach((field, index) => {
				if (col_relation.dest_col === field.column) {
					debugger;
					field.value = returnValue;
					this.$set(this.allField, index, field);
				}
			});
		},
		async setCallbackColumnValue(serviceCall, condition) {
			let url = this.getServiceUrl(serviceCall.app, serviceCall.service, 'select');
			let req = {
				serviceName: serviceCall.service,
				colNames: ['*'],
				condition: condition
			};
			const res = await this.$http.post(url, req);
			if (res.data.state === 'SUCCESS') {
				console.log('setCallbackColumnValue,', res.data.data);
				if (res.data.data.length > 0) {
					const resData = res.data.data[0];
					const colArr = Object.keys(resData);
					this.allField.forEach((field, index) => {
						colArr.forEach(item => {
							if (item === field.column) {
								field.value = resData[item];
								this.$set(this.allField, index, field);
							}
						});
					});
				}
			}
			return;
			let returnValue = '';
			switch (serviceCall.value.type) {
				case 'value':
					returnValue = serviceCall.value.value;
					break;
				case 'calc':
					(() => {
						let valueArr = serviceCall.value.value.value.map(serviceCallitem => {
							if (serviceCallitem.type === 'col') {
								const finalArr = this.allField.filter(col => col.column === serviceCallitem.val);
								if (finalArr.length > 0) {
									return finalArr[0].value;
								}
							} else if (serviceCallitem.type === 'value') {
								return serviceCallitem.val;
							}
						});
						switch (serviceCall.value.value.type) {
							case 'add': //加
								valueArr.forEach(item => {
									returnValue += Number(item);
								});
								break;
							case 'sub': //减
								returnValue = valueArr[0] - valueArr[1];
								break;
							case 'multi': //乘
								returnValue = 1;
								valueArr.forEach(item => {
									returnValue *= Number(item);
								});
								break;
							case 'divide': //除
								returnValue = valueArr[0] / valueArr[1];
								break;
						}
					})();
					break;
				case 'col':
					(() => {
						this.allField.forEach(col => {
							if (col.column === serviceCall.value.value) {
								returnValue = col.value;
							}
						});
					})();
					break;
			}
			this.allField.forEach((item, index) => {
				if (item.column === serviceCall.dest_col) {
					item.value = returnValue;
					this.$set(this.allField, index, item);
				}
			});
		},
		onItemButtons(e) {
			this.$emit('on-form-item', e);
			return e;
		},
		getAllField() {
			console.log('getAllField', this.fields);
			if (this.fields.length > 0) {
				this.allField = this.fields.map((itemData, index) => {
					this.fieldModel[itemData.column] = itemData.value;
					let item = this.fieldModel;
					if (itemData.defaultValue) {
						itemData.value = itemData.defaultValue;
					}
					if (itemData.hasOwnProperty('isShowExp') && item.hasOwnProperty(itemData.column)) {
						itemData['showExp'] = this.evalInTo(itemData, item);
						// itemData['showExp'] = this.colItemShowExps(itemData, item) ;
						itemData['display'] = itemData.isShowExp && itemData.isShowExp.length > 0 ? this.colItemShowExps(itemData, item) : true;
					} else {
						itemData['showExp'] = itemData['showExp'] || true;
					}
					itemData.valid = {
						column: itemData.column,
						valid: true,
						msg: '不能为空!'
					};
					this.specialCol.forEach(special => {
						if (special.column === itemData.column) {
							special.value ? (this.fieldModel[itemData.column] = special.value) : '';
							special.value ? (itemData['value'] = special.value) : '';
							special.disabled ? (itemData['disabled'] = special.disabled) : '';
							special.display ? (itemData['display'] = special.display) : '';
						}
					});
					return itemData;
				});
			}
		},
		onValChange(e) {
			const self = this;
			if (e.type === 'number') {
				this.fieldModel[e.column] = Number(e.value);
			} else {
				this.fieldModel[e.column] = e.value;
			}
			console.log('valueChange', e, this.fieldModel[e.column], this.fieldModel);
			const fieldModel = JSON.parse(JSON.stringify(this.fieldModel));
			this.allField = this.allField.map((item, index) => {
				item.display = item.isShowExp && item.isShowExp.length > 0 ? this.colItemShowExps(item, this.fieldModel) : true;
				if (item.column === e.column) {
					item.value = e.value;
				}
				return item;
			});
			this.more_config.col_relation.forEach(col_relation => {
				// if (col_relation.watch_col.includes(e.column)) {
				//当前字段是监控字段
				if (col_relation.watch_col.some(item => e.column === item)) {
					//当前改变值的字段存在于watch_col中
					let colArr = this.allField.filter(field => col_relation.watch_col.includes(field.column));
					if (colArr.every(item => item.value)) {
						self.setRelationColumnValue(self.allField, colArr, col_relation);
					}
				}
			});
			// return
			this.more_config.service_call_cfg.forEach(serviceCallCfg => {
				if (serviceCallCfg.watch_col.some(item => e.column === item)) {
					//当前字段是监控字段
					//拿到所有监控字段的数据
					let colArr = this.allField.filter(field => serviceCallCfg.watch_col.includes(field.column));
					//所有监控字段都有值
					if (colArr.every(item => item.value)) {
						if (serviceCallCfg.req.condition) {
							let condition = [];
							serviceCallCfg.req.condition.forEach(cond => {
								if (cond.value.valueType && cond.value.valueType === 'rowData' && cond.value.valueKey) {
									// cond.value = fieldModel[cond.value.valueKey];
									console.log('FILELLLL', this.fieldModel);
									// this.$set(cond,'value', fieldModel[cond.value.valueKey])
									condition.push({ colName: cond.colName, ruleType: 'eq', value: fieldModel[cond.value.valueKey] });
								}
							});
							self.setCallbackColumnValue(serviceCallCfg, condition);
						}
					}
				}
			});
		},
		onValBlur(e) {
			const self = this;
			this.$emit('value-blur', e);
		},
		getDetailfieldModel() {
			return this.fieldModel;
		},
		getFieldModel() {
			let valid = 0;
			let showsNum = 0;
			console.log('this.$refs', this.$refs);

			this.allField.map((item, index) => {
				let valids = this.$refs.fitem[index].getValid();
				console.log('字段校验', valids);
				if (item.display) {
					showsNum++;
					if (valids.valid) {
						valid++;
					}
					// if (item.isRequire && item.valid.valid && item.value !== '') {
					// 	valid++;
					// } else if (!item.isRequire) {
					// 	valid++;
					// }
				}
			});
			console.log(valid, showsNum);
			if (valid === showsNum) {
				console.log('表单校验通过', showsNum, valid, this.fieldModel);
				let model = {};
				switch (this.pageType) {
					case 'update':
						for (let key in this.fieldModel) {
							if (this.oldFieldModel[key] !== this.fieldModel[key]) {
								model[key] = this.fieldModel[key];
							}
						}
						break;
					case 'add':
						for (let key in this.fieldModel) {
							if (this.fieldModel[key] === '') {
								delete this.fieldModel[key];
							}
						}
						model = this.fieldModel;
						break;
					default:
						model = this.fieldModel;
						break;
				}
				console.log('this.fieldModel', this.fieldModel, model);
				if (Object.keys(model).length > 0) {
					return model;
				} else {
					uni.showToast({
						title: '没有需要提交的数据',
						icon: 'none'
					});
				}
			} else {
				console.log('表单校验失败', showsNum, valid, this.fieldModel);
				uni.showToast({
					title: '请填写完信息后，再尝试提交',
					icon: 'none'
				});
				return false;
			}
		},
		getCascaderVal(val) {
			if (val) {
				this.$emit('get-cascader-val', val);
			} else {
				this.$emit('get-cascader-val');
			}
		},
		onReset() {
			this.allField = this.deepClone(this.oldField);
			try {
				return true;
			} catch (e) {
				return false;
				//TODO handle the exception
			}
		}
	},
	watch: {
		fields: {
			handler: function(newval, old) {
				console.log('newval', newval, this.allField);
				this.getAllField();
			},
			deep: true
		},
		moreConfig: {
			handler: function(newval, old) {
				// this.getAllField();
				if (newval) {
					this.more_config = this.deepClone(newval);
				}
			},
			deep: true
		},
		fieldModel: {
			deep: true,
			handler(newVal, oldVal) {}
		}
	}
};
</script>

<style lang="less"></style>
